/*
* Copyright (c) 2025 Shenzhen Kaihong Digital Industry Development Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

use std::{collections::BTreeMap, path::Path};

use anyhow::Context;
use askama::Template;
use convert_case::{Case, Casing};
use ohmw_codegen::msg_def::{MsgDef, MsgDefMap};

#[derive(Template)]
#[template(path = "test.js.askama")]
struct TestJsTemplate<'a> {
    pkg_name: &'a str,
    msg_defs: &'a BTreeMap<String, MsgDef>,
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    println!("cargo:rerun-if-changed=templates/test.js.askama");

    let msgs_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../../idl/msg");
    let test_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("test");

    let msg_def_map = MsgDefMap::from_msgs_dir(&msgs_dir).await
        .context("failed to scan message definitions")?;

    for (pkg_name, msg_defs) in msg_def_map.map.iter() {
        for (msg_name, _) in msg_defs.iter() {
            println!("cargo:rerun-if-changed=../../../idl/msg/{}/{}.msg", pkg_name, msg_name);
        }

        let template = TestJsTemplate {
            pkg_name,
            msg_defs,
        };
        let content = template.render()
            .context(format!("failed to render test template for {}", pkg_name))?;
        let test_js_path = test_dir.join(format!("{}.js", pkg_name));
        if !test_js_path.exists() || tokio::fs::read_to_string(&test_js_path).await.is_ok_and(|s| s != content) {
            tokio::fs::write(test_js_path, content).await
                .context(format!("failed to write test template for {}", pkg_name))?;
        }
    }

    Ok(())
}
